
#ifndef _HEADER
#define _HEADER

#ifdef _LINUX
#include "rally.linux.h"
#elif _WIN32
#include "rally.win32.h"
#endif

//========= ===============
//			     Macro
//=========================
#define STDIN_FILENO	0
#define STDOUT_FILENO	1
#define STDERR_FILENO	2

#define SEM_PRIVATE		0
#define SEM_SHARED 		1

#define COMM_NONBLOCK 	0
#define COMM_BLOCK		1

#define PROC_RINDEXD	0
#define PROC_RSTATD 	1
#define PROC_RPOINTD 	2
#define PROC_RCACHED	3

#define MAX_FILENAME_LENGTH 	255
#define MAX_HOSTNAME_LENGTH	255
#define MAX_LINE_LENGTH		1024

#define ETH_ID        "eth0"
#define STRERR		strerror(errno);
//#define NSIG			34

#ifdef _DEBUG
#define FLOG_IN(fname)		rp_log(LOG_DEBUG, fname, "Enter ...");				
#define FLOG_OUT(fname)		rp_log(LOG_DEBUG, fname, "Exit ..."); 
#else
#define FLOG_IN(fname)		
#define FLOG_OUT(fname)
#endif	// _DEBUG
				
extern char **environ;

//========= ===============
//		      Internal Datatype
//========================
typedef enum Log_Level {
	LOG_FATAL,
	LOG_CRITICAL,
	LOG_ERROR,
	LOG_WARNING,
	LOG_NOTICE,
	LOG_INFO,
	LOG_DEBUG,
	LOG_TRACE
} Log_Level;

typedef enum State {
	/*	state remain the same	*/ 
	SS_FAILED,			// FAILED --> fork process fails
	SS_IDLE,
	SS_BUSY,
	/*	state changed during the last interval	*/
	SC_FAILED,
	SC_IDLE,
	SC_BUSY,
	SC_EXITED,
	/*	state to be changed to for the next internval	*/
	ST_EXIT,			// rstatd set this state to let rpointd exit
	ST_PAUSE,
	ST_RESUME,
} State;

typedef struct {
	rp_mutex_t mutex;
	rp_thread_t tid;
	State state;
} Status;	

typedef enum OpCode {
	OP_NONE,
	OP_END,					// TODO: Why do we have this?
	OP_REPLICA,
	OP_SHUTDOWN,
	OP_SHUTDOWN_FORCE,
	OP_PAUSE,
	OP_RESUME,
} OpCode;

typedef	enum Err {
	E_OK,
	E_BUSY,
	E_INVALID,
	E_ERROR,
	E_FATAL,
} Err;

typedef struct KeyValue {
    char *key;
    char *value;
} KeyValue;

typedef struct Task {

} Task;

typedef struct Tnode {
	Task task;
	struct Tnode *next;
	struct Tnode *prev;
} Tnode;

typedef struct Tqueue {
	rp_mutex_t mutex;
	int qlength;
	int ntask;
	Tnode *head;
	Tnode *tail;
} Tqueue;

typedef struct OpArg {
	// TODO: what should it contain?
} OpArg;
typedef struct Cmd {
	OpCode code;
	OpArg arg;
} Cmd;
typedef struct Cnode {
	Cmd cmd;
	struct Cnode *next;
	struct Cnode *prev;
} Cnode;
typedef struct Cqueue {
	rp_mutex_t mutex;
	int qlength;		// The max Cmd items in the queue
	int ncmd;		// The Cmd items already in the queue	
	Cnode *head;
	Cnode *tail;
} Cqueue;

/*==== Info	==== */
typedef struct Score {		// Rpointd process status
	rp_sem_t sem;		// ussed by both rstatd and rpointd
	int heartbeat;			// written by rpointd, cleared by rpointd	
	State state;				// written by rpointd, read by rstatd
	OpCode code;			// written by rstatd, cleared by rpointd
} Score; 

/*
typedef struct Snode {			// TODO: should we support fine-grain lock on Snode?
	Score *score;
	rp_pid_t pid;
	int fd;
       struct Snode *next; 
	struct Snode *prev; 
} Snode;

typedef struct Scoreboard {
	rp_mutex_t mutex;
	int total;					// the number of total rpointd process
	int idle;					// the number of idle rpointd process
	Snode *head;
	Snode *tail;
} Scoreboard;

*/
/*
typedef Snode Pnode;
typedef struct Ptable {
	rp_mutex_t mutex;
	int count;
	Pnode *head;
	Pnode *tail;
} Ptable;
*/
//========= ===============
//			Global Variables
//=========================

static char *log_level_array[8] = {
	"LOG_FATAL",
	"LOG_CRITICAL",
	"LOG_ERROR",
	"LOG_WARINING",
	"LOG_NOTICE",
	"LOG_INFO",
	"LOG_DEBUG",
	"LOG_TRACE"
};

//========= ===============
//			Rstatd Variables
//=========================

//========= ===============
//			Rindexd Variables
//=========================

//========= ===============
//			Rpointd Variables
//=========================

//========= ===============
//			Rcached Variables
//=========================

#endif	// _HEADER

